/* This file is part of swapper project
 *
 * Copyright (C) 2020 The Swapper Project Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.swapper.mock.config;

import com.swapper.mock.MockConfig;
import com.swapper.mock.annotations.MockSize;

import java.lang.annotation.Annotation;
import java.util.Random;

public final class MockSizeConfig extends MockConfig {
  private final int[] range = {4, 4};

  public MockSizeConfig() {
  }

  public MockSizeConfig(int lower, int upper) {
    setRange(lower, upper);
  }

  @SuppressWarnings("all")
  @Override
  public void withAnnotationConfig(Annotation annotation) {
    if (annotation instanceof MockSize) {
      MockSize config = (MockSize) annotation;
      int[] range = config.value();
      if (range.length == 1) {
        setRange(range[0], range[0]);
      } else if (range.length == 2) {
        setRange(range[0], range[1]);
      } else {
        throw new IllegalArgumentException("The range array length must be 1 or 2.");
      }
    }
  }

  public int[] getRange() {
    return range.clone();
  }

  public void setRange(int lower, int upper) {
    if (lower < 0) {
      throw new IllegalArgumentException("The size must be non-negative.");
    }
    if (lower > upper) {
      throw new IllegalArgumentException("The upper bound is less than the lower bound.");
    }
    range[0] = lower;
    range[1] = upper;
  }

  public void setSize(int size) {
    if (size < 0) {
      throw new IllegalArgumentException("The count of the group must be non-negative.");
    }
    range[0] = range[1] = size;
  }

  public int random(Random random) {
    if (range[0] == range[1]) {
      return range[0];
    } else {
      return range[0] + random.nextInt(range[1] - range[0] + 1);
    }
  }
}
